package com.igen.rxnetaction.connection;

import android.Manifest;
import android.content.Context;
import android.support.annotation.RequiresPermission;

import com.igen.rxnetaction.connection.networkobserving.NetworkObservingStrategy;
import com.igen.rxnetaction.connection.networkobserving.strategy.LollipopNetworkObservingStrategy;
import com.igen.rxnetaction.connection.networkobserving.strategy.MarshmallowNetworkObservingStrategy;
import com.igen.rxnetaction.connection.networkobserving.strategy.PreLollipopNetworkObservingStrategy;

import rx.Observable;

/**
 * Created by hp on 2017/3/21.
 */

public class RxNetwork {

    protected RxNetwork() {
    }

    /**
     * Creates a new instance of the ReactiveNetwork class
     *
     * @return ReactiveNetwork object
     */
    public static RxNetwork create() {
        return new RxNetwork();
    }

    /**
     * Observes network connectivity. Information about network state, type and typeName are contained in
     * observed Connectivity object.
     *
     * @param context Context of the activity or an application
     * @return RxJava Observable with Connectivity class containing information about network state,
     * type and typeName
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    public static Observable<Connectivity> observeNetworkConnectivity(final Context context) {
        final NetworkObservingStrategy strategy;

        if (Preconditions.isAtLeastAndroidMarshmallow()) {
            strategy = new MarshmallowNetworkObservingStrategy();
        } else if (Preconditions.isAtLeastAndroidLollipop()) {
            strategy = new LollipopNetworkObservingStrategy();
        } else {
            strategy = new PreLollipopNetworkObservingStrategy();
        }

        return observeNetworkConnectivity(context, strategy);
    }

    /**
     * Observes network connectivity. Information about network state, type and typeName are contained in
     * observed Connectivity object. Moreover, allows you to define NetworkObservingStrategy.
     *
     * @param context  Context of the activity or an application
     * @param strategy NetworkObserving strategy to be applied - you can use one of the existing
     *                 strategies {@link PreLollipopNetworkObservingStrategy},
     *                 {@link LollipopNetworkObservingStrategy} or create your own custom strategy
     * @return RxJava Observable with Connectivity class containing information about network state,
     * type and typeName
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    public static Observable<Connectivity> observeNetworkConnectivity(final Context context,
                                                                      final NetworkObservingStrategy strategy) {
        Preconditions.checkNotNull(context, "context == null");
        Preconditions.checkNotNull(strategy, "strategy == null");
        return strategy.observeNetworkConnectivity(context);
    }
}
